<?php
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/model/fields/TextField.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/utils/DirectoryUtils.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/utils/FileUtils.php';

include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/database/core/FilenameCollection.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/core/Filename.php';

include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/database/core/IAutoUpdateColumn.php';

class File extends TextField implements IAutoUpdateColumn
{	
	
	public    $path;
	public    $shouldPrefix;
	public    $file_data;
	public    $context;
	
	public $shouldAppendColumnToPath;
	
	protected $filenameMemento;
	public static $fileKeyCache;
	
	/**
	 * undocumented function
	 *
	 * @array $fileTypes array of allowed fileTypes
	 * @return File
	 **/
	
	public function __construct(IDatabaseRecord &$object, $length = null, $path = null, $shouldPrefix = true, $shouldAppendColumnToPath = false)
	{
		// previoulsy was using debug_backtrace()
		// but we found an issue when (we think) php was running as CGI.  The ['object']
		// key was not being passed.
		// signature was:
		// public function __construct($length = null, $defaultValue = null)
		// $this->model was being set via:
		// $tmp =  debug_backtrace();
		// $this->model        = &$tmp[1]['object'];

		$config = PhormConfig::getConfig();

		$this->model                    = $object;
		$this->field_type               = 'string';
		$this->length                   = ($length) ? $length : 50;
		$this->path                     = $path == null ? $config->mediaPath."/".strtolower(get_class($this->model)) : $path;
		$this->shouldPrefix             = $shouldPrefix;
		$this->filenameMemento          = new FilenameCollection();
		$this->shouldAppendColumnToPath = $shouldAppendColumnToPath;
		$this->context                  =& $_FILES;
	}
	
	public function getPath()
	{
		if ($this->shouldAppendColumnToPath)
		{
			if (!strpos($this->path, $this->column))
				return $this->path.'/'.$this->column;
			else
				return $this->path;
		}
	}
	
	public function update()
	{
		if(!$this->file_data)
			$this->file_data = &$this->column;
			
		if (isset($_FILES[$this->file_data]) && $this->context[$this->file_data]['size'] > 0 && $_FILES[$this->file_data]['error'] == 0 && $this->isDirty)
		{
		
			if ($this->shouldAppendColumnToPath)
			{
				if (!strpos($this->path, $this->column))
					$this->path = $this->path.'/'.$this->column;
			}
		
			DirectoryUtils::createDirectoryChain($this->path);		
			
			if ($this->file_data)
			{
				if ($this->model->isNew)
				{
					FileUtils::updateFile($this->context[$this->file_data], $this->path."/".$this->data['value']);
				}
				else
				{
					if ($this->data['value'])
					{
						//FileUtils::delete($this->path.'/'.$this->data['value']);
						foreach($this->filenameMemento as $filename)
						{
							FileUtils::delete($this->path.'/'.$filename);
						}
					}
					
					FileUtils::updateFile($this->context[$this->file_data], $this->path."/".$this->data['value']);
				}
			}
			/*else
			{
				foreach($_FILES as $fileData)
				{		
					// this is going to assume that we will NOT be uploading multiple files with the same filename
				
					if ($fileData['name'] == $this->data['value'] || $fileData['name'] == substr($this->data['value'], 7))
					{
						if ($this->model->isNew)
						{
								FileUtils::updateFile($fileData, $this->path."/".$this->data['value']);
						}
						else
						{
							if ($this->data['value'])
							{
								//FileUtils::delete($this->path.'/'.$this->data['value']);
								foreach($this->filenameMemento as $filename)
								{
									FileUtils::delete($this->path.'/'.$filename);
								}
							}
							
							FileUtils::updateFile($fileData, $this->path."/".$this->data['value']);
						}
					}
				}
			}*/
		}
		else if ($this->filenameMemento->length)
		{
			foreach($this->filenameMemento as $filename)
			{
				FileUtils::delete($this->path.'/'.$filename);
			}
		}
	}
	
	private function formatFilename(&$value)
	{
		$prefix = $this->shouldPrefix ? 7 : 0;
		$suffix = 4;
		
		$parts  = explode('.', $value);
		$length = ($this->length - ($prefix + $suffix));
		
		$value  = substr($parts[0], 0, $length).'.'.$parts[1];
	}
	
	protected function locateFileKey($filename)
	{
		if(!self::$fileKeyCache)
		{
			self::$fileKeyCache = array();
		}
		else
		{
			if(array_key_exists($filename, self::$fileKeyCache))
			{
				$this->file_data = self::$fileKeyCache[$filename];
				return;
			}
		}
		
		foreach($_FILES as $key=>$value)
		{
			if($value['name'] == $filename){
				$this->file_data = $key;
				self::$fileKeyCache[$filename] = $key;
				break;
			}
		}
	}
	
	public function handleUserDefinedValue(&$value)
	{ 	
		// we may want to add some kind of if(is_file())
		// here so that this would run until the new prefixed filename
		// is not found.
		$this->locateFileKey($value);
		
		if($this->shouldPrefix && (strlen($value)+7) > $this->length)
		{
			$this->formatFilename($value);
		}
		else if(strlen($value) > $this->length)
		{
			$this->formatFilename($value);
		}
		
		if (isset($this->data['value']))
			$this->filenameMemento->addItem(new Filename($this->data['value']));
		
		if ($this->shouldPrefix)
			$value = FileUtils::prefixFilename($value);
	}
	
	/*public function toHTML()
	{ 
		$value = @$this->value;
		$html  = "<tr class=\"phorm-toHTML-row\"\>\n\t";
		$html .= "<td class=\"phorm-toHTML-label\">".$this->column.": </td>\n\t";
		$html .= "<td class=\"phorm-toHTML-input\"><input name=\"{$this->column}\" type=\"file\" value=\"{$value}\"></td>\n";
		$html .= "<tr>\n";
		
		return $html;
	}*/
}
?>
